#ifndef _BASE_BLKQUEUE_H
#define _BASE_BLKQUEUE_H

#include <stdint.h>

enum gen_blk_queue_state
{
    GEN_BLK_QUEUE_EMPTY,            // 空
    GEN_BLK_QUEUE_FULL,             // 满
    GEN_BLK_QUEUE_HALFFULL,         // 半满即不满也不空
};

/* 块状队列 - 使用环形缓冲区实现 */ 
struct gen_blk_queue
{
    uint8_t *mempool;                  // 队列的内存池
    
    uint16_t block_size;            // 块大小
    uint16_t block_num;             // 块数量

    uint32_t read_mirror : 1;       // 读镜像标记
    uint32_t read_index : 15;       // 读索引
    uint32_t write_mirror : 1;      // 写镜像标记
    uint32_t write_index : 15;      // 写索引
};

/* 初始化队列 */
void gen_blk_queue_init(struct gen_blk_queue *queue, void *mempool, int blk_size, int mempool_size);
/* 复位队列 */
void gen_blk_queue_reset(struct gen_blk_queue *queue);
/* 推送数据 */
int gen_blk_queue_push(struct gen_blk_queue *queue, const uint8_t *ptr, int num);
int gen_blk_queue_push_block(struct gen_blk_queue *queue, const uint8_t *ptr);
/* 强行推送数据(即使数据有可能被覆盖) */
int gen_blk_queue_push_force(struct gen_blk_queue *queue, const uint8_t *ptr, int num);
int gen_blk_queue_push_block_force(struct gen_blk_queue *queue, const uint8_t *ptr);
/* 弹出数据 */
int gen_blk_queue_pop(struct gen_blk_queue *queue, uint8_t *ptr, int num);
int gen_blk_queue_pop_block(struct gen_blk_queue *queue, uint8_t *ptr);
/* 读 */
int gen_blk_queue_read(struct gen_blk_queue *queue, uint8_t *ptr, int num);
/* 偏移的读 */
int gen_blk_queue_read_offset(struct gen_blk_queue *queue, uint8_t *ptr, int offset, int num);
/* 已使用块数量 */
int gen_blk_queue_block_num(struct gen_blk_queue *queue);
/* 队列的状态 */
static inline enum gen_blk_queue_state gen_blk_queue_status(struct gen_blk_queue *queue)
{
    if (queue->read_index == queue->write_index)
    {
        if (queue->read_mirror == queue->write_mirror)
            return GEN_BLK_QUEUE_EMPTY;
        else
            return GEN_BLK_QUEUE_FULL;
    }
    return GEN_BLK_QUEUE_HALFFULL;
}

/* 空闲块数量 */
#define gen_blk_queue_space_len(queue) ((queue)->block_num - gen_blk_queue_block_num(queue))




#endif

